package dice.sinanya.listener;

import com.forte.qqrobot.anno.Filter;
import com.forte.qqrobot.anno.Listen;
import com.forte.qqrobot.beans.messages.msgget.*;
import com.forte.qqrobot.beans.messages.result.GroupMemberInfo;
import com.forte.qqrobot.beans.messages.result.inner.Group;
import com.forte.qqrobot.beans.messages.types.MsgGetTypes;
import com.forte.qqrobot.beans.messages.types.PowerType;
import com.forte.qqrobot.beans.types.KeywordMatchType;
import com.forte.qqrobot.listener.result.ListenResult;
import com.forte.qqrobot.sender.MsgSender;
import com.simbot.component.mirai.messages.MiraiBaseMsgGet;
import com.simbot.component.mirai.messages.MiraiEvents;
import com.simbot.component.mirai.messages.MiraiMemberLeaveEvent;
import dice.sinanya.dice.MakeNickToSender;
import dice.sinanya.dice.game.Welcome;
import dice.sinanya.dice.system.Bot;
import dice.sinanya.dice.system.Properties;
import dice.sinanya.entity.EntityLogTag;
import dice.sinanya.entity.EntityTypeMessages;
import dice.sinanya.entity.EntityWelcome;
import dice.sinanya.exceptions.*;
import dice.sinanya.flow.Flow;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.regex.Pattern;

import static com.forte.qqrobot.beans.messages.types.MsgGetTypes.discussMsg;
import static dice.sinanya.db.reviewed.SelectReviewed.checkReviewEd;
import static dice.sinanya.db.system.InsertBot.deleteBot;
import static dice.sinanya.system.MessagesBanList.groupSwitchHashMap;
import static dice.sinanya.system.MessagesListenResult.MSG_IGNORE;
import static dice.sinanya.system.MessagesListenResult.MSG_INTERCEPT;
import static dice.sinanya.system.MessagesSystem.isRunning;
import static dice.sinanya.system.MessagesSystem.loginInfo;
import static dice.sinanya.system.MessagesWelcome.welcomes;
import static dice.sinanya.tools.checkdata.CheckIsNumbers.isNumeric;
import static dice.sinanya.tools.checkdata.imal.GetZk.*;
import static dice.sinanya.tools.checkdata.imal.LeaveGroup.leaveGroup;
import static dice.sinanya.tools.getinfo.BanList.*;
import static dice.sinanya.tools.getinfo.GetAdminList.getAdminList;
import static dice.sinanya.tools.getinfo.GetMessagesProperties.*;
import static dice.sinanya.tools.getinfo.GetNickName.getGroupName;
import static dice.sinanya.tools.getinfo.GetNickName.getNickNameByQq;
import static dice.sinanya.tools.getinfo.LogTag.checkOthorLogTrue;
import static dice.sinanya.tools.getinfo.LogTag.getOtherLogTrue;
import static dice.sinanya.tools.getinfo.LogText.setLogText;
import static dice.sinanya.tools.getinfo.SwitchBot.getBot;
import static dice.sinanya.tools.getinfo.WhiteList.*;
import static dice.sinanya.tools.makedata.FullWidth2halfWidth.fullWidth2halfWidth;
import static dice.sinanya.tools.makedata.ReplyTool.reply;
import static dice.sinanya.tools.makedata.SendToMaster.sendToManager;
import static dice.sinanya.tools.makedata.Sender.sender;
import static dice.sinanya.tools.makedata.StringFormatById.stringFormatById;

public class Listener implements MakeNickToSender {
    private static final Logger Log = LogManager.getLogger(Listener.class.getName());

    private final Pattern commandHeader = Pattern.compile("(?s)^[ ]*[,，.。][ ]*.+");
    private final Pattern chineseRegex = Pattern.compile("([\\u4e00-\\u9fa5]+)");
    private final String tagMe = stringFormatById("[cq:at,qq=%s]", loginInfo.getLoginId());


    @Listen(value = MsgGetTypes.privateMsg, sort = 500)
    @Filter(value = "(?s)^[ ]*[@][ ]*.*", keywordMatchType = KeywordMatchType.TRIM_REGEX)
    public ListenResult privateMsg(MsgGet msgGet, MsgGetTypes msgGetTypes, MsgSender msgSender, PrivateMsg msgPrivate) throws NotProipertiesSwitch {
        if (entityBanProperties.getMaster().contains(msgPrivate.getQQCode())) {
            EntityTypeMessages entityTypeMessages = new EntityTypeMessages(msgGetTypes, msgSender, msgGet, msgPrivate);
            new Properties(entityTypeMessages).prop();
        } else {
            msgSender.SENDER.sendPrivateMsg(msgPrivate.getQQCode(), "只有骰主可以使用此命令修改设置项");
        }
        return MSG_INTERCEPT;
    }

//    @Listen.ByName(MiraiEvents.botReloginEvent)
//    public ListenResult relogin() {
//        new Update().restart();
//        return MSG_IGNORE;
//    }

    @Listen(value = MsgGetTypes.privateMsg, sort = 500)
    @Filter
    public ListenResult privateMsgProperties(MsgGet msgGet, MsgGetTypes msgGetTypes, MsgSender msgSender, PrivateMsg msgPrivate) {

        String msg = fullWidth2halfWidth(msgPrivate.getMsg());
        if (!entitySystemProperties.isRunning()) {
            msgSender.SENDER.sendPrivateMsg(msgPrivate.getQQCode(), "目前本骰休假中，不提供服务");
            return MSG_INTERCEPT;
        }
        msgGet.setMsg(msg);
        EntityTypeMessages entityTypeMessages = new EntityTypeMessages(msgGetTypes, msgSender, msgGet, msgPrivate);
        reply(entityTypeMessages);
        if (!msg.matches(commandHeader.toString()) && !isNumeric(msg)) {
            return MSG_IGNORE;
        }
        if (checkQqInBanList(entityTypeMessages.getFromQqString())) {
            return MSG_INTERCEPT;
        }
        String botMsg = msg.toLowerCase();
        if (botMsg.contains("bot") && !botMsg.contains("update")) {
            new Bot(entityTypeMessages).info();
        } else if (botMsg.contains("bot update")) {
            new Bot(entityTypeMessages).update();
        } else {
            try {
                new Flow(entityTypeMessages).toPrivateAndGroup();
            } catch (Exception e) {
                Log.error(e.getMessage(), e);
            }
        }
        return MSG_IGNORE;
    }

    @Listen(value = MsgGetTypes.groupMsg, sort = 500)
    public ListenResult groupMsg(MsgGet msgGet, MsgGetTypes msgGetTypes, MsgSender msgSender, GroupMsg msgGroup) throws InterruptedException, NotEnableBySimpleException, NotEnableInGroupException {
        String msg = fullWidth2halfWidth(msgGroup.getMsg());
        if (!entitySystemProperties.isRunning()) {
            return MSG_INTERCEPT;
        }
        msgGet.setMsg(msg);
        EntityTypeMessages entityTypeMessages = new EntityTypeMessages(msgGetTypes, msgSender, msgGet, msgGroup);
        if ((checkBeBanOrInBan(entityTypeMessages) == MSG_INTERCEPT)) {
            return MSG_INTERCEPT;
        }

        try {
            if (checkBotSwitch(entityTypeMessages) == MSG_INTERCEPT) {
                return MSG_INTERCEPT;
            }
        } catch (OnlyManagerException e) {
            Log.error(e.getMessage(), e);
        }

        try {
            if (msg.contains("welcome")) {
                Pattern pattern = Pattern.compile("^(\\[cq:at,qq=[0-9]+.*])*[ ]*[,，.。][ ]*welcome[ ]*.*", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
                if (pattern.matcher(msgGroup.getMsg().trim().toLowerCase()).find()) {
                    Welcome welcome = new Welcome(entityTypeMessages);
                    welcome.set();
                }
            }
        } catch (NotEnableException | OnlyManagerException | NotEnableInGroupException e) {
            Log.error(e.getMessage(), e);
        }

        if (!getBot(entityTypeMessages.getFromGroup())) {
            return MSG_INTERCEPT;
        }
        reply(entityTypeMessages);

        boolean findBotExit = msg.matches("(?s)^[ ]*[,，.。][ ]*bot[ ]*exit.*");
        if (isRunning && (entitySystemProperties.isZookeeper() && checkEnable(entityTypeMessages))) {
            if (!getInGroupZNodeActive(msgGroup.getGroupCode(), entityTypeMessages) && !msgGet.getMsg().contains("rank")) {
                return MSG_IGNORE;
            }
        }
        if (msg.matches(commandHeader.toString()) && !findBotExit) {
            if (entityBanProperties.isReviewed() && !checkReviewEd(entityTypeMessages.getFromGroup()) && !msg.contains("bot exit")) {
                msgSender.SENDER.sendGroupMsg(entityTypeMessages.getFromGroupString(), "本群未通过审核，因此除.bot exit退群功能外，其余无法使用。请前往群162279609进行审核");
                return MSG_INTERCEPT;
            }
            try {
                new Flow(entityTypeMessages).toGroup();
            } catch (Exception e) {
                Log.error(e.getMessage(), e);
            }
        }
        setLogsForText(entityTypeMessages);
        return MSG_IGNORE;
    }

    @Listen(value = discussMsg, sort = 500)
//    @Filter(value = "(?s)^[ ]*[,，.。][ ]*.*", keywordMatchType = KeywordMatchType.TRIM_REGEX)
    public ListenResult discussMsg(MsgGet msgGet, MsgGetTypes msgGetTypes, MsgSender msgSender, DiscussMsg msgDisGroup) throws InterruptedException, NotEnableBySimpleException, NotEnableInGroupException {
        String msg = fullWidth2halfWidth(msgDisGroup.getMsg());
        if (!entitySystemProperties.isRunning()) {
            return MSG_INTERCEPT;
        }
        msgGet.setMsg(msg);
        EntityTypeMessages entityTypeMessages = new EntityTypeMessages(msgGetTypes, msgSender, msgGet, msgDisGroup);
        if (checkBeBanOrInBan(entityTypeMessages) == MSG_INTERCEPT) {
            return MSG_INTERCEPT;
        }

        try {
            if (checkBotSwitch(entityTypeMessages) == MSG_INTERCEPT) {
                return MSG_INTERCEPT;
            }
        } catch (OnlyManagerException e) {
            Log.error(e.getMessage(), e);
        }

        if (!getBot(entityTypeMessages.getFromGroup())) {
            return MSG_INTERCEPT;
        }
        reply(entityTypeMessages);

        boolean findBotExit = msg.matches("(?s)^[ ]*[,，.。][ ]*bot[ ]*exit.*");
        if (isRunning && (entitySystemProperties.isZookeeper() && checkEnable(entityTypeMessages))) {
            if (!getInGroupZNodeActive(msgDisGroup.getGroupCode(), entityTypeMessages) && !msgGet.getMsg().contains("rank")) {
                return MSG_IGNORE;
            }
        }
        if (msg.matches(commandHeader.toString()) && !findBotExit) {
            if (entityBanProperties.isReviewed() && !checkReviewEd(entityTypeMessages.getFromGroup()) && !msg.contains("bot exit")) {
                msgSender.SENDER.sendDiscussMsg(entityTypeMessages.getFromGroupString(), "本群未通过审核，因此除.bot exit退群功能外，其余无法使用。请前往群162279609进行审核");
                return MSG_INTERCEPT;
            }
            try {
                new Flow(entityTypeMessages).toDisGroup();
            } catch (Exception e) {
                Log.error(e.getMessage(), e);
            }
        }
        setLogsForText(entityTypeMessages);
        return MSG_IGNORE;
    }

    @Listen(MsgGetTypes.groupMemberReduce)
    public ListenResult groupMemberDecrease(MsgSender msgSender, GroupMemberReduce groupMemberReduce, MiraiBaseMsgGet miraiBaseMsgGet) throws BanMasterOrManagerGroupException, InterruptedException {
        if (!(miraiBaseMsgGet instanceof MiraiMemberLeaveEvent)) {
            return MSG_IGNORE;
        }
        MiraiMemberLeaveEvent miraiMemberLeaveEvent = (MiraiMemberLeaveEvent) miraiBaseMsgGet;
        if (groupMemberReduce.getBeOperatedQQ().equals(msgSender.getLoginInfo().getQQ())) {
            checkGroupActiveDelete(groupMemberReduce.getGroupCode());
        }
        if (groupMemberReduce.getBeOperatedQQ().equals(msgSender.getLoginInfo().getQQ()) && entityBanProperties.isBanGroupBecauseReduce()) {
            if (entityBanProperties.isBanUserBecauseReduce()) {
                checkMasterOrManagerGroup(msgSender, groupMemberReduce.getOperatorQQ(), groupMemberReduce.getGroupCode());
                sendToManager(msgSender, "已被移出群" + groupMemberReduce.getGroupCode() + "中，将群和操作者"
                        + miraiMemberLeaveEvent.getEvent().getMember().getNameCard() + "(" + groupMemberReduce.getOperatorQQ() + ")拉黑");
                if (checkQqInWhiteList(Long.parseLong(groupMemberReduce.getOperatorQQ()))) {
                    sendToManager(msgSender, groupMemberReduce.getOperatorQQ() + "为白名单用户，放弃拉黑");
                } else {
                    insertQqBanList(groupMemberReduce.getOperatorQQ(), "被踢出群" + groupMemberReduce.getGroupCode());

                    Group[] groupList = msgSender.GETTER.getGroupList().getList();
                    for (Group group : groupList) {
                        GroupMemberInfo member = null;
                        try {
                            member = msgSender.GETTER.getGroupMemberInfo(group.getCode(), groupMemberReduce.getOperatorQQ());
                        } catch (Exception ignore) {

                        }
                        if (member == null) {
                            continue;
                        }
                        PowerType powerType = member.getPowerType();
                        PowerType myPowerType = msgSender.GETTER.getGroupMemberInfo(group.getCode(), msgSender.GETTER.getLoginQQInfo().getQQ()).getPowerType();
                        boolean powerThanMe = powerType.TYPE > myPowerType.TYPE;
                        if (powerThanMe) {
                            sendToManager(msgSender, "发现在群" + group.getName() + "(" + group.getCode() + ")中有黑名单成员" + member.getCard() + "(" + member.getQQ() + ")且权限更高,将预防性退群");
                            msgSender.SENDER.sendGroupMsg(group.getCode(), "发现在群" + group.getName() + "(" + group.getCode() + ")中有黑名单成员" + member.getCard() + "(" + member.getQQ() + ")且权限更高,将预防性退群");
                            leaveGroup(msgSender, group.getCode());
                            deleteBot(Long.parseLong(group.getCode()));
                        }
                    }
                }
            } else {
                sendToManager(msgSender, "已被移出群" + "(" + groupMemberReduce.getGroupCode() + ")中，将群拉黑");
            }
            if (checkGroupInWhiteList(groupMemberReduce.getGroupCodeNumber())) {
                sendToManager(msgSender, groupMemberReduce.getGroupCode() + "为白名单群，放弃拉黑");
            } else {
                insertGroupBanList(groupMemberReduce.getGroupCode(), "被" + groupMemberReduce.getOperatorQQ() + "踢出");
            }
        }
        return MSG_IGNORE;
    }

    @Listen(MsgGetTypes.groupMemberIncrease)
    public ListenResult groupMemberIncrease(MsgSender msgSender, GroupMemberIncrease groupMemberIncrease) {
        if (Long.parseLong(groupMemberIncrease.getBeOperatedQQ()) != loginInfo.getLoginId()) {
            long fromGroup = groupMemberIncrease.getGroupCodeNumber();
            try {
                Thread.sleep(1000);
                if (entityGame.isWelcomeSwitch() && welcomes.containsKey(fromGroup)) {
                    if (welcomes.getOrDefault(fromGroup, new EntityWelcome(false, "")).isEnable()) {
                        String groupId = groupMemberIncrease.getGroup();
//                        msgSender.SENDER.sendDiscussMsg(groupId, stringFormatById(welcomes.get(fromGroup).getText(), "[CQ:at,qq=" + groupMemberIncrease.getBeOperatedQQ() + "]"));
                        String messages = stringFormatById(welcomes.get(fromGroup).getText(), "[CQ:at,qq=" + groupMemberIncrease.getBeOperatedQQ() + "]");
                        if (!messages.equals("")) {
                            msgSender.SENDER.sendGroupMsg(groupId, messages);
                        }
                    }
                }
            } catch (InterruptedException e) {
                Log.error(e.getMessage(), e);
            }
        } else if (Long.parseLong(groupMemberIncrease.getBeOperatedQQ()) == loginInfo.getLoginId()) {
            String nick = makeNickToSender("未找到");
            try {
                nick = makeNickToSender(msgSender.GETTER.getGroupMemberInfo(groupMemberIncrease.getGroupCode(), groupMemberIncrease.getOperatorQQ(), false).getCard());
            } catch (Exception ignore) {

            }
            if (checkGroupInBanList(groupMemberIncrease.getGroupCode())) {
                msgSender.SENDER.sendGroupMsg(groupMemberIncrease.getGroupCode(), "检测到加入黑名单群，即将退群");
                sendToManager(msgSender,
                        "被强制邀请进黑名单群: " + makeGroupNickToSender(getGroupName(msgSender, groupMemberIncrease.getGroup())) + "(" + groupMemberIncrease.getGroupCode() + ")，邀请人: "
                                + nick + "(" + groupMemberIncrease.getOperatorQQ() + ")");
                leaveGroup(msgSender, groupMemberIncrease.getGroupCode());
            } else {
                if (!entitySystemProperties.isPublicMode() && checkQqInWhiteList(Long.parseLong(groupMemberIncrease.getOperatorQQ()))) {
                    sendToManager(msgSender,
                            "已加入白名单群: " + makeGroupNickToSender(getGroupName(msgSender, groupMemberIncrease.getGroup())) + "(" + groupMemberIncrease.getGroupCode() + ")，邀请人: "
                                    + nick + "(" + groupMemberIncrease.getOperatorQQ() + ")");
                    msgSender.SENDER.sendGroupMsg(groupMemberIncrease.getGroupCode(), entityBanProperties.getAddGroup());
                    return MSG_INTERCEPT;
                }
                if (!entitySystemProperties.isPublicMode() && checkGroupInWhiteList(groupMemberIncrease.getGroupCodeNumber())) {
                    sendToManager(msgSender,
                            "已加入白名单群: " + makeGroupNickToSender(getGroupName(msgSender, groupMemberIncrease.getGroup())) + "(" + groupMemberIncrease.getGroupCode() + ")，邀请人: "
                                    + nick + "(" + groupMemberIncrease.getOperatorQQ() + ")");
                    msgSender.SENDER.sendGroupMsg(groupMemberIncrease.getGroupCode(), entityBanProperties.getAddGroup());
                    return MSG_INTERCEPT;
                }

                ArrayList<String> adminList = getAdminList(msgSender, groupMemberIncrease.getGroupCode());
                for (String admin : adminList) {
                    if (checkQqInBanList(admin)) {
                        sendToManager(msgSender,
                                "已加入群（若无处理邀请提示则为讨论组）: " + makeGroupNickToSender(getGroupName(msgSender, groupMemberIncrease.getGroup())) + "(" + groupMemberIncrease.getGroupCode() + ")，其中" + getNickNameByQq(msgSender, admin) + makeNickToSender(admin) + "处于黑名单内，已退出");
                        msgSender.SENDER.sendGroupMsg(groupMemberIncrease.getGroupCode(), getNickNameByQq(msgSender, admin) + makeNickToSender(admin) + "处于黑名单内，将预防性退出");
                        leaveGroup(msgSender, groupMemberIncrease.getGroupCode());
                        return MSG_INTERCEPT;
                    }
                }
//                if (!"0".equals(groupMemberIncrease.getOperatorQQ())) {
                sendToManager(msgSender,
                        "已加入群（若无处理邀请提示则为讨论组）: " + makeGroupNickToSender(getGroupName(msgSender, groupMemberIncrease.getGroup())) + "(" + groupMemberIncrease.getGroupCode() + ")");
                msgSender.SENDER.sendGroupMsg(groupMemberIncrease.getGroupCode(), entityBanProperties.getAddGroup());
            }
            return MSG_INTERCEPT;
        }
        return MSG_IGNORE;
    }

    @Listen(MsgGetTypes.groupAddRequest)
    public ListenResult groupAddRequest(MsgSender msgSender, GroupAddRequest groupAddRequest) {
        if (groupAddRequest.getRequestType().isAdd()) {
            return MSG_IGNORE;
        }
        if (!entitySystemProperties.isRunning()) {
            msgSender.SETTER.setGroupAddRequest(groupAddRequest.getFlag(), groupAddRequest.getRequestType(), false, "本骰休假中，不提供服务");
            msgSender.SENDER.sendPrivateMsg(groupAddRequest.getQQCode(),
                    "本骰休假中，不提供服务");
            return MSG_INTERCEPT;
        }

        if (!entitySystemProperties.isPublicMode() && checkQqInWhiteList(groupAddRequest.getQQCodeNumber())) {
            msgSender.SETTER.setGroupAddRequest(groupAddRequest.getFlag(), groupAddRequest.getRequestType(), true, "白名单用户");
            sendToManager(msgSender,
                    "收到白名单群: " + makeGroupNickToSender(getGroupName(msgSender, groupAddRequest.getGroup())) + "(" + groupAddRequest.getGroupCode() + ")，邀请人: "
                            + makeNickToSender(msgSender.GETTER.getGroupMemberInfo(groupAddRequest.getGroupCode(), groupAddRequest.getQQCode()).getCard()) + "(" + groupAddRequest.getQQCode() + ")");
            insertGroupWhiteList(groupAddRequest.getGroupCodeNumber());
            msgSender.SENDER.sendGroupMsg(groupAddRequest.getGroupCode(), entityBanProperties.getAddGroup());
            return MSG_INTERCEPT;
        }

        if (!entitySystemProperties.isPublicMode() && checkGroupInWhiteList(groupAddRequest.getGroupCodeNumber())) {
            msgSender.SETTER.setGroupAddRequest(groupAddRequest.getFlag(), groupAddRequest.getRequestType(), true, "白名单群");
            msgSender.SENDER.sendGroupMsg(groupAddRequest.getGroupCode(), entityBanProperties.getAddGroup());
            return MSG_INTERCEPT;
        } else if (!entitySystemProperties.isPublicMode()) {
            msgSender.SETTER.setGroupAddRequest(groupAddRequest.getFlag(), groupAddRequest.getRequestType(), false, "非白名单群");
            sendToManager(msgSender,
                    makeNickToSender(msgSender.GETTER.getGroupMemberInfo(groupAddRequest.getGroupCode(), groupAddRequest.getQQCode()).getCard()) + "(" + groupAddRequest.getQQCode() + ")邀请进群: " + makeGroupNickToSender(getGroupName(msgSender, groupAddRequest.getGroup()) + "(" + groupAddRequest.getGroupCode() + ")，群和邀请人均不在白名单内，已拒绝"));
            return MSG_INTERCEPT;
        }

        if (entityBanProperties.isLeaveGroupByBan() && checkGroupInBanList(groupAddRequest.getGroupCode())) {
            msgSender.SETTER.setGroupAddRequest(groupAddRequest.getFlag(), groupAddRequest.getRequestType(), false, "黑名单群");
            sendToManager(msgSender,
                    "(" + groupAddRequest.getQQCode() + ")邀请进入黑名单群: " + makeGroupNickToSender(getGroupName(msgSender, groupAddRequest.getGroup()) + "(" + groupAddRequest.getGroupCode() + ")已拒绝"));
            return MSG_INTERCEPT;
        }
        if (checkQqInBanList(groupAddRequest.getQQCode())) {
            msgSender.SETTER.setGroupAddRequest(groupAddRequest.getFlag(), groupAddRequest.getRequestType(), false, "黑名单用户");
            sendToManager(msgSender,
                    "黑名单用户: " + "(" + groupAddRequest.getQQCode() + ")邀请进入群: " + makeGroupNickToSender(getGroupName(msgSender, groupAddRequest.getGroup())) + "(" + groupAddRequest.getGroupCode() + ")已拒绝");
            return MSG_INTERCEPT;
        }


        if (entityBanProperties.isAutoInputGroup()) {
            msgSender.SETTER.setGroupAddRequest(groupAddRequest.getFlag(), groupAddRequest.getRequestType(), true, "正常加入");
            sendToManager(msgSender,
                    "收到群: " + makeGroupNickToSender(getGroupName(msgSender, groupAddRequest.getGroup())) + "(" + groupAddRequest.getGroupCode() + ")，邀请人: "
                            + makeNickToSender(getNickNameByQq(msgSender, groupAddRequest.getQQCode())) + "(" + groupAddRequest.getQQCode() + ")的邀请，已通过");
            msgSender.SENDER.sendGroupMsg(groupAddRequest.getGroupCode(), entityBanProperties.getAddGroup());
            return MSG_INTERCEPT;
        } else {
            return MSG_IGNORE;
        }
    }


    @Listen(MsgGetTypes.groupBan)
    public ListenResult groupBan(GroupBan groupBan, MsgSender msgSender) throws BanMasterOrManagerGroupException, InterruptedException {
        if (groupBan.getBanType().isBan() && entityBanProperties.isBanGroupBecauseBan() && groupBan.getBeOperatedQQ().equals(msgSender.getLoginInfo().getQQ())) {
            clearGroupActive();
            checkMasterOrManagerGroup(msgSender, groupBan.getOperatorQQ(), groupBan.getGroup());
            long fromGroup = Long.parseLong(groupBan.getGroup());
            long fromQq = Long.parseLong(groupBan.getOperatorQQ());
            if (checkQqInWhiteList(fromQq)) {
                sendToManager(msgSender, "在群" + makeGroupNickToSender(getGroupName(msgSender, groupBan.getGroup())) + "("
                        + fromGroup + ")中被禁言，操作者为: " + makeNickToSender(msgSender.GETTER.getGroupMemberInfo(groupBan.getGroup(), groupBan.getOperatorQQ()).getCard()) + "(" + fromQq + ")处于本骰子白名单中，因此不做额外操作");
                return MSG_IGNORE;
            } else {
                insertQqBanList(String.valueOf(fromQq), "在群" + makeGroupNickToSender(getGroupName(msgSender, groupBan.getGroup())) + "("
                        + fromGroup + ")中被禁言，操作者为: " + makeNickToSender(msgSender.GETTER.getGroupMemberInfo(groupBan.getGroup(), groupBan.getOperatorQQ()).getCard()) + "(" + fromQq + ")");
                sendToManager(msgSender, "在群" + makeGroupNickToSender(getGroupName(msgSender, groupBan.getGroup())) + "("
                        + fromGroup + ")中被禁言，操作者为: " + makeNickToSender(msgSender.GETTER.getGroupMemberInfo(groupBan.getGroup(), groupBan.getOperatorQQ()).getCard()) + "(" + fromQq + ")");
            }
            if (checkGroupInWhiteList(fromGroup)) {
                sendToManager(msgSender, "于群" + makeGroupNickToSender(getGroupName(msgSender, groupBan.getGroup())) + "("
                        + fromGroup + ")中被禁言，但由于同时处于本骰子白名单中，因此不做额外操作");
                return MSG_IGNORE;
            } else {
                sendToManager(msgSender, "于群" + makeGroupNickToSender(getGroupName(msgSender, groupBan.getGroup())) + "("
                        + fromGroup + ")中被禁言，已退出并拉黑");
                leaveGroup(msgSender, String.valueOf(fromGroup));
                deleteBot(fromGroup);
                insertGroupBanList(String.valueOf(fromGroup), "被禁言");
            }
        }
        return MSG_INTERCEPT;
    }


    @Listen(MsgGetTypes.friendAdd)
    public ListenResult friendAdd(FriendAdd friendAdd, MsgSender msgSender) {
        if (!entitySystemProperties.isPublicMode() && checkQqInWhiteList(friendAdd.getCodeNumber())) {
            sendToManager(msgSender, "白名单已开启: " + makeNickToSender(getNickNameByQq(msgSender, friendAdd.getQQCode())) + "(" + friendAdd.getCodeNumber() + ") 的好友邀请，处于白名单中已同意");
            return MSG_INTERCEPT;
        }
        if (entityBanProperties.isAutoAddFriends()) {
            sendToManager(msgSender, makeNickToSender(getNickNameByQq(msgSender, friendAdd.getQQCode())) + "(" + friendAdd.getCodeNumber() + ") 的好友邀请，已自动同意");
            msgSender.SENDER.sendPrivateMsg(friendAdd.getQQCode(), entityBanProperties.getAddFriend());
        }
        return MSG_IGNORE;
    }

    @Listen(MsgGetTypes.friendAddRequest)
    public ListenResult friendAddRequest(FriendAddRequest friendAddRequest, MsgSender msgSender) {
        if (!entitySystemProperties.isRunning()) {
            msgSender.SETTER.setFriendAddRequest(friendAddRequest.getFlag(), "", false);
            msgSender.SENDER.sendPrivateMsg(friendAddRequest.getQQCode(), "本骰休假中，不提供服务");
            return MSG_INTERCEPT;
        }

        if (!entitySystemProperties.isPublicMode() && checkQqInWhiteList(friendAddRequest.getCodeNumber())) {
            msgSender.SETTER.setFriendAddRequest(friendAddRequest.getFlag(), "", true);
            msgSender.SENDER.sendPrivateMsg(friendAddRequest.getQQCode(), entityBanProperties.getAddFriend());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Log.error(e.getMessage(), e);
            }
            return MSG_INTERCEPT;
        } else if (!entitySystemProperties.isPublicMode() && !checkQqInWhiteList(friendAddRequest.getCodeNumber())) {
            msgSender.SETTER.setFriendAddRequest(friendAddRequest.getFlag(), "", false);
            msgSender.SENDER.sendPrivateMsg(friendAddRequest.getQQCode(), "很抱歉，您不在白名单内，请联系: " + entityBanProperties.getMaster());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Log.error(e.getMessage(), e);
            }
            sendToManager(msgSender, "白名单已开启: " + makeNickToSender(getNickNameByQq(msgSender, friendAddRequest.getQQ())) + "(" + friendAddRequest.getQQCode() + ") 的好友邀请，不在白名单中已拒绝");
            return MSG_INTERCEPT;
        }

        if (checkQqInBanList(friendAddRequest.getQQ())) {
            msgSender.SETTER.setFriendAddRequest(friendAddRequest.getFlag(), "", false);
            msgSender.SENDER.sendPrivateMsg(friendAddRequest.getQQCode(), entityBanProperties.getRefuseFriendByBan());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Log.error(e.getMessage(), e);
            }
            sendToManager(msgSender, makeNickToSender(getNickNameByQq(msgSender, friendAddRequest.getQQ())) + "(" + friendAddRequest.getQQCode() + ") 的好友邀请，处于黑名单中已拒绝");
            return MSG_INTERCEPT;
        }

        if (entityBanProperties.isAutoAddFriends()) {
            msgSender.SETTER.setFriendAddRequest(friendAddRequest.getFlag(), "", true);
            msgSender.SENDER.sendPrivateMsg(friendAddRequest.getQQCode(), entityBanProperties.getAddFriend());
            return MSG_INTERCEPT;
        } else {
            return MSG_IGNORE;
        }
    }

    private ListenResult checkBeBanOrInBan(EntityTypeMessages entityTypeMessages) {
        if (checkQqInBanList(entityTypeMessages.getFromQqString()) && entityBanProperties.isIgnoreBanUser() && !checkQqInWhiteList(entityTypeMessages.getFromQq())) {
            return MSG_INTERCEPT;
        }

        if (checkGroupInBanList(entityTypeMessages.getFromGroupString()) && entityBanProperties.isLeaveGroupByBan()) {
            if (checkGroupInWhiteList(entityTypeMessages.getFromGroup())) {
                return MSG_IGNORE;
            }
            try {
                sender(entityTypeMessages, "检测到处于黑名单群中，正在退群");
                sendToManager(entityTypeMessages, "检测到处于黑名单群" + makeGroupNickToSender(getGroupName(entityTypeMessages)) + "("
                        + entityTypeMessages.getFromGroup() + ")中，正在退群");
            } catch (Exception ignore) {

            }
            leaveGroup(entityTypeMessages.getMsgSender(), entityTypeMessages.getFromGroupString());
            return MSG_INTERCEPT;
        }
        return MSG_IGNORE;
    }

    private ListenResult checkBotSwitch(EntityTypeMessages entityTypeMessages) throws OnlyManagerException, InterruptedException {
        String messages = entityTypeMessages.getMsgGet().getMsg().toLowerCase();

        if (!messages.contains("bot")) {
            return MSG_IGNORE;
        }

        String tagBotOff = ".*[,，.。][ ]*bot[ ]*off.*";
        String tagBotInfo = ".*[,，.。][ ]*bot.*";
        String tagBotExit = ".*[,，.。][ ]*bot[ ]*exit.*";
        String tagBotUpdate = ".*[,，.。][ ]*bot[ ]*update.*";

        String tagBotOn = ".*[,，.。][ ]*bot[ ]*on.*";
        String qqId = String.valueOf(loginInfo.getLoginId());
        boolean botOn = messagesContainsAtMe(messages, tagBotOn, tagMe) || messagesBotForAll(messages, tagBotOn)
                || messagesContainsQqId(qqId, messages, tagBotOn);
        if (botOn) {
            checkAudit(entityTypeMessages);
            new Bot(entityTypeMessages).on();
            return MSG_INTERCEPT;
        }
        boolean botOff = messagesContainsAtMe(messages, tagBotOff, tagMe) || messagesBotForAll(messages, tagBotOff)
                || messagesContainsQqId(qqId, messages, tagBotOff);
        if (botOff) {
            checkAudit(entityTypeMessages);
            new Bot(entityTypeMessages).off();
            return MSG_INTERCEPT;
        }
        boolean botExit = messagesContainsAtMe(messages, tagBotExit, tagMe) || messagesBotForAll(messages, tagBotExit)
                || messagesContainsQqId(qqId, messages, tagBotExit);
        if (botExit) {
            checkAudit(entityTypeMessages);
            new Bot(entityTypeMessages).exit();
            return MSG_INTERCEPT;
        }
        boolean botUpdate = (messagesContainsAtMe(messages, tagBotUpdate, tagMe)
                || messagesBotForAll(messages, tagBotUpdate) || messagesContainsQqId(qqId, messages, tagBotUpdate));
        if (botUpdate) {
            new Bot(entityTypeMessages).update();
            return MSG_INTERCEPT;
        }
        boolean botInfo = (messagesContainsAtMe(messages, tagBotInfo, tagMe) || messagesBotForAll(messages, tagBotInfo)
                || messagesContainsQqId(qqId, messages, tagBotInfo));

        if (botInfo) {
            new Bot(entityTypeMessages).info();
            return MSG_INTERCEPT;
        }
        return MSG_INTERCEPT;
    }

    private boolean messagesContainsAtMe(String messages, String tagBotSwitch, String tagMe) {
        return messages.trim().matches(tagBotSwitch) && messages.trim().contains(tagMe);
    }

    private boolean messagesBotForAll(String messages, String tagBotSwitch) {
        return messages.trim().matches(tagBotSwitch) && !messages.trim().contains("[cq:at")
                && !messages.matches(".*[0-9]+.*") && messages.matches("^[ ]*" + tagBotSwitch.substring(2, tagBotSwitch.length() - 2) + "[ ]*$");
    }

    private boolean messagesContainsQqId(String qqId, String messages, String tagBotSwitch) {
        return messages.trim().matches(tagBotSwitch)
                && (messages.trim().contains(qqId) || messages.trim().contains(qqId.substring(qqId.length() - 5)));
    }

    private void checkAudit(EntityTypeMessages entityTypeMessages) throws OnlyManagerException {
        if (entityTypeMessages.getMsgGetTypes() == discussMsg) {
            return;
        }
        GroupMemberInfo member = entityTypeMessages.getMsgSender().GETTER.getGroupMemberInfo(entityTypeMessages.getFromGroupString(), entityTypeMessages.getFromQqString());

        boolean boolIsAdmin = member.getPowerType() != PowerType.MEMBER;
        boolean boolIsAdminOrInDiscuss = boolIsAdmin
                || entityTypeMessages.getMsgGetTypes() == discussMsg;
        if (!boolIsAdminOrInDiscuss) {
            throw new OnlyManagerException(entityTypeMessages);
        }
    }

    private void setLogsForText(EntityTypeMessages entityTypeMessages) {
        if (checkOthorLogTrue(entityTypeMessages.getFromGroupString())) {
            if ("s".equals(entityTypeMessages.getMsgGet().getMsg().toLowerCase())) {
                sender(entityTypeMessages, "kp开始描述");
                return;
            }
            if ("o".equals(entityTypeMessages.getMsgGet().getMsg().toLowerCase())) {
                sender(entityTypeMessages, "kp描述结束");
                return;
            }
            setLogText(entityTypeMessages, new EntityLogTag(entityTypeMessages.getFromGroupString(),
                    getOtherLogTrue(entityTypeMessages.getFromGroupString())), entityTypeMessages.getMsgGet().getMsg());
        }
    }

    private void checkMasterOrManagerGroup(MsgSender msgSender, String qq, String groupId) throws BanMasterOrManagerGroupException {
        if (entityBanProperties.getManagerGroup().equals(groupId)) {
            for (String qqId : entityBanProperties.getMaster()) {
                msgSender.SENDER.sendPrivateMsg(qqId, "已触发拉黑条件，但当前群是管理群，停止拉黑");
            }
            throw new BanMasterOrManagerGroupException();
        }

        if (entityBanProperties.getMaster().contains(qq)) {
            for (String qqId : entityBanProperties.getMaster()) {
                msgSender.SENDER.sendPrivateMsg(qqId, "已触发拉黑条件，但当前目标在Master列表内，停止拉黑");
            }
            throw new BanMasterOrManagerGroupException();
        }
    }

    private boolean checkEnable(EntityTypeMessages entityTypeMessages) throws NotEnableInGroupException, NotEnableBySimpleException {
        return groupSwitchHashMap.containsKey(entityTypeMessages.getFromGroup()) && groupSwitchHashMap.get(entityTypeMessages.getFromGroup()).isZookeeper();
    }
}
